package com.tbvtc.agriculturalcreditchainserver2025.controller.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tbvtc.agriculturalcreditchainserver2025.entity.CropRecords;
import com.tbvtc.agriculturalcreditchainserver2025.entity.Orders;
import com.tbvtc.agriculturalcreditchainserver2025.entity.recognize.OcrResponse;
import com.tbvtc.agriculturalcreditchainserver2025.entity.recognize.WordResult;
import com.tbvtc.agriculturalcreditchainserver2025.exception.FoodException;
import com.tbvtc.agriculturalcreditchainserver2025.properties.BaiDuProperties;
import com.tbvtc.agriculturalcreditchainserver2025.service.ICropRecordsService;
import com.tbvtc.agriculturalcreditchainserver2025.service.IpfsService;
import com.tbvtc.agriculturalcreditchainserver2025.utils.RUtils;
import com.tbvtc.agriculturalcreditchainserver2025.utils.Result;
import com.tbvtc.agriculturalcreditchainserver2025.utils.ResultCodeEnum;
import com.tbvtc.agriculturalcreditchainserver2025.utils.recognize.FieldDataConverter;
import com.tbvtc.agriculturalcreditchainserver2025.utils.recognize.OcrDataProcessor;
import com.tbvtc.agriculturalcreditchainserver2025.utils.recognize.OcrDataTransformer;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@Tag(name = "田间档案")
@RequestMapping("/fieldArchives")
public class FieldArchivesController {
    @Resource
    private ICropRecordsService cropRecordsService;
    private final RestTemplate restTemplate;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private OcrDataProcessor odcDataProcessor;
    @Resource
    private OcrDataTransformer ocrDataTransformer;
    @Resource
    private FieldDataConverter fieldConverter;
    @Resource
    private IpfsService ipfsService;

    // 构造函数注入RestTemplate
    public FieldArchivesController(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private BaiDuProperties baiDuProperties;

    @Operation(summary = "查询田间档案")
    @Parameters({@Parameter(name = "reportType", description = "阶段名称")
            , @Parameter(name = "archivesName", description = "档案名称")})
    @GetMapping
    public Result getFieldArchives(@RequestParam(value = "reportType", required = false) String stageName, String archivesName) {

        return RUtils.success(cropRecordsService.getFieldArchives(stageName, archivesName));
    }

    @Operation(summary = "获取档案数量")
    @GetMapping("/count")
    public Result getFieldArchivesCount() {
        return RUtils.success(cropRecordsService.count());
    }

    @Operation(summary = "本月新增")
    @GetMapping("/count/month")
    public Result getFieldArchivesCountMonth() {
        LocalDateTime now = LocalDateTime.now();
        //获取本月第一天
        LocalDateTime beginTime = now.withDayOfMonth(1);
        long count = cropRecordsService.count(new LambdaQueryWrapper<CropRecords>()
                .between(CropRecords::getCreateTime, beginTime, now));
        return RUtils.success(count);
    }

    /**
     * 田间档案文字识别
     * @param file
     * @return
     */
    @PostMapping("/recognize")
    @Operation(summary = "文字识别")
    public Result wordRecognition(@RequestPart("file") MultipartFile file) throws IOException {
        OcrResponse text = getText(file);
        Map<Integer, String> process = odcDataProcessor.process(text);
        Map<String, Object> convert = fieldConverter.convert(process);

        return RUtils.success(convert);

    }

    public String getAccessToken() {
        String url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials"
                + "&client_id=" + baiDuProperties.getApiKey()
                + "&client_secret=" + baiDuProperties.getSecretKey();
        JsonObject pestJson = JsonParser.parseString(Objects.requireNonNull(restTemplate.getForObject(url, String.class))).getAsJsonObject();//获取图像识别结果
        String accessToken = pestJson.get("access_token").getAsString();
        redisTemplate.opsForValue().set("baiduAccessToken", accessToken, 20, TimeUnit.DAYS);
        return accessToken;

    }

    public OcrResponse getText(MultipartFile file) {
        String token = redisTemplate.opsForValue().get("baiduAccessToken");
        if (token == null) {
            token = getAccessToken();

        }
        // 构建完整的请求URL，包含access_token参数
        String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting" +
                "?access_token=" + token;
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // 设置请求参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        try {
            // 关键修复：正确将图片转换为Base64编码
            byte[] fileBytes = file.getBytes();
            String base64Image = Base64.getEncoder().encodeToString(fileBytes);
            params.add("image", base64Image);
        } catch (IOException e) {
            throw new FoodException(ResultCodeEnum.REQUEST_FAILED);
        }
        // 构建请求实体
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
        // 发送POST请求并获取响应
        ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            try {

                return objectMapper.readValue(response.getBody(), OcrResponse.class);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            // 获取动态数组（无需关心长度，直接遍历）
        } else {
            throw new RuntimeException("调用百度OCR API失败，状态码：" + response.getStatusCodeValue());
        }
    }
}
